package com.li.toolkit.utils;

import com.itextpdf.text.log.Logger;
import com.itextpdf.text.log.LoggerFactory;
import com.li.toolkit.constant.LogConst;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.util.encoders.Base64;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.SecureRandom;

/**
 * Baee64 格式转换, 以及密码加密解密
 *
 * @author LiDong
 * @version 1.0.0
 * @createTime 2/19/2022 10:12 AM
 */
public final class PasswordUtils {

    private static final Logger logger = LoggerFactory.getLogger(PasswordUtils.class);

    private static Key key;
    private static final String KEY_STR = "myKey";
    private static final String CHARSET = "UTF-8";
    private static final String ALGORITHM = "DES";

    private PasswordUtils() {
    }

    /**
     * Base64解密
     *
     * @param str 字符串
     * @return
     */
    public static String base64Decode(String str) {
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            return new String(decoder.decodeBuffer(str), StandardCharsets.UTF_8);
        } catch (Exception e) {
            logger.error(LogConst.LOG_FAILURE_PREFIX + e.getMessage());
            return null;
        }
    }

    /**
     * Base64加密
     *
     * @param str 字符串
     * @return
     */
    public static String base64Encode(String str) {
        try {
            if (StringUtils.isEmpty(str)) {
                byte[] bytes = new byte[1];
                return Base64.toBase64String(bytes);
            }
            byte[] bytes = new byte[str.length()];
            int length = str.length();
            for (int i = 0; i < length; i++) {
                char[] chars = str.toCharArray();
                bytes[i] = (byte) chars[i];
            }
            return Base64.toBase64String(bytes);
        } catch (Exception e) {
            logger.error(LogConst.LOG_FAILURE_PREFIX + e.getMessage());
            return "";
        }
    }


    /**
     * Des 对称加密
     *
     * @param str 字符串
     * @return
     */
    public static String desEncrypt(String str) {
        generatorKey();
        // 基于BASE64编码，接收byte[]并转换成String
        BASE64Encoder encoder = new BASE64Encoder();
        try {
            // 按utf8编码
            byte[] bytes = str.getBytes(CHARSET);
            // 获取加密对象
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 初始化密码信息
            cipher.init(Cipher.ENCRYPT_MODE, key);
            // 加密
            byte[] doFinal = cipher.doFinal(bytes);
            // byte[]to encode好的String 并返回
            return encoder.encode(doFinal);
        } catch (Exception e) {
            logger.error(LogConst.LOG_FAILURE_PREFIX + e.getMessage());
            return StrUtils.EMPTY_STR;
        }
    }

    /**
     * Des 对称解密
     *
     * @param str 字符串
     * @return
     */
    public static String desDecrypt(String str) {
        generatorKey();
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            //将字符串decode成byte[]
            byte[] bytes = decoder.decodeBuffer(str);
            //获取解密对象
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            //初始化解密信息
            cipher.init(Cipher.DECRYPT_MODE, key);
            //解密
            byte[] doFial = cipher.doFinal(bytes);
            return new String(doFial, CHARSET);
        } catch (Exception e) {
            logger.error(LogConst.LOG_FAILURE_PREFIX + e.getMessage());
            return StrUtils.EMPTY_STR;
        }
    }

    /**
     * 生成 key
     */
    public static void generatorKey() {
        try {
            // 生成DES算法对象
            KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
            // 运用SHA1安全策略
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            // 设置上密钥种子
            secureRandom.setSeed(KEY_STR.getBytes());
            // 初始化基于SHA1的算法对象
            generator.init(secureRandom);
            // 生成密钥对象
            key = generator.generateKey();
        } catch (Exception e) {
            logger.error(LogConst.LOG_FAILURE_PREFIX + e.getMessage());
        }
    }


}
